#include "linklist.h"

// 1.创建一个空的单向链表(有头单向链表)
link_node_t *CreateEpLinkList()
{
    link_list_t p = (link_list_t)malloc(sizeof(link_node_t));
    if (NULL == p)
    {
        // create empty 创造空
        perror("CreateEpLinkList err");
        return NULL;
    }
    p->next = NULL;
    return p;
}
// 2.向单向链表的指定位置插入数据
// p保存链表的头指针 post 插入的位置 data插入的数据
// 头　－> 第０个　-> 第一个
int InsertIntoPostLinkList(link_node_t *p, int post, datatype data)
{
// 容错判断
    if (post < 0 || post > LengthLinkList(p))
    {
        perror("InsertIntoPostLinkList");
        return -1;
    }
// 只想ｐｏｓｔ前一个
    for (int i = 0; i < post; i++)
        p = p->next;
    // link_node_t *h = CreateEpLinkList();
// 新开辟一个空间
    link_list_t pnew = (link_list_t)malloc(sizeof(link_list_t));
    if (NULL == p)
    {
        perror("CreateEpLinkList err");
        return -1;
    }
//先让新开辟的空间指向ｐｏｓｔ 
    pnew->next = p->next;
//再让ｐｏｓｔ前一个指向新开的的空间 
    p->next = pnew;
// 赋值
    pnew->data = data;
    return 0;

}
// 3.遍历单向链表
void ShowLinkList(link_node_t *p)
{
    // 去头
    p = p->next;
    while (p)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    puts(" ");
}

// 4.求单向链表长度的函数
int LengthLinkList(link_node_t *p)
{
    // 去除头节点后的长度
    int len = 0;
    // 如果有下一个
    while (p->next)
    {
        p = p->next;
        len++;
    }
    return len;
}
// 5.删除单向链表中指定位置的数据 post 代表的是删除的位置
//  0 1 2 3
int DeletePostLinkList(link_node_t *p, int post)
{
    // 容错判断
    // post 从０开始，所以要比ｌｅｎ小１才对
    if (post > LengthLinkList(p) || perror < 0)
    {
        perror("DeletePostLinkList Error");
        return -1;
    }
    // 在ｐｏｓｔ－１停下　
    for (int i = 0; i < post; i++)
    {
        // 向后移动一位
        p = p->next;
    }
    // p->next是指向ｐｏｓｔ位置的指针
    link_node_t *h = p->next;
    // ｐｏｓｔ前一个ｎｅｘｔ指向ｐｏｓｔ下一个ｎｅｘｔ
    p->next = p->next->next;
    // 释放空间
    free(h);
    return 0;
}
// 6.判断单向链表是否为空 1代表空 0代表非空
int IsEpLinkList(link_node_t *p)
{
    return NULL == p->next;
}
// 7.修改指定位置的数据 post 被修改的位置 data修改成的数据
int ChangePostLinkList(link_node_t *p, int post, datatype data)
{
    // １容错
    // 长度比最大下表大１
    if (post >= LengthLinkList(p) || post < 0)
    {
        printf("ChangePostLinkList");
        return -1;
    }
    // ２指向ｐｏｓｔ

    for (int i = 0; i <= post; i++)
        p = p->next;
    // ３修改内容
    p->data = data;
    return 0;
}
// /8.查找指定数据出现的位置 data被查找的数据 //search 查找
int SearchDataLinkList(link_node_t *p, datatype data)
{
    // 需要先把长度记录下来。因为每次后移都会让长度－１
    int l = LengthLinkList(p);
    // 砍头
    p = p->next;
    // printf("::::%d\n ",p->data);
    for (int i = 0; i < l; i++)
    {
        if (p->data == data)
            return i;
        p = p->next;
    }
    return -1;
}
// 9.删除单向链表中出现的指定数据,data代表将单向链表中出现的所有data数据删除
int DeleteDataLinkList(link_node_t *p, datatype data)
{
    // 需要先把长度记录下来。因为每次后移都会让长度－１
    int l = LengthLinkList(p);
    link_node_t *q = p;
    // 删除数据的个数
    int n = 0;
    // 砍头
    p = p->next;
    // printf("::::%d\n ",p->data);
    for (int i = 0; i < l; i++)
    {
        if (p->data == data)
        {
            DeletePostLinkList(q, i);
            n++;
        }
        p = p->next;
    }
    return n;
}
// void ReverseLinkList(link_node_t *p)
// {
// }
